package ru.nlezhnev.services.request_processor;

import java.sql.Connection;
import java.sql.SQLException;

import ru.nlezhnev.data_models.FarmActionsModel;
import ru.nlezhnev.data_models.FarmDataModel;
import ru.nlezhnev.db.Database;
import ru.nlezhnev.utils.ASObjectUtils;
import ru.nlezhnev.utils.MapUtils;
import ru.nlezhnev.utils.TypeUtils;
import flex.messaging.io.amf.ASObject;

public class UpdateData extends FarmRequestProcessor {
	static private final String[] OUTGOING_ACTIONS_PATH = { "farm_data",
			"actions", "outgoing" };
	static private final String[] INCOMING_ACTIONS_PATH = { "farm_data",
			"actions", "incoming" };
	static private final String[] FRIENDS_PATH = { "friends_data" };
	static private final String[] RATING_PATH = { "ratings", "outgoing" };

	public UpdateData(byte[] inputData, String vid, String methodName) {
		super(inputData, vid, methodName);
	}

	protected Object performRequest() throws SQLException {
		ASObject changes = (ASObject) data.get("changes");
		ASObject deletedData = (ASObject) data.get("deletedData");

		processOutgoingActions(changes);

		Connection conn = Database.getInstance().getConnection();
		FarmDataModel farm = new FarmDataModel(conn, uid);

		MapUtils.destroy(farm.getData(), deletedData);
		MapUtils.merge(farm.getData(), changes);

		ASObjectUtils.deleteByPath(OUTGOING_ACTIONS_PATH, farm.getData());
		ASObjectUtils.deleteByPath(INCOMING_ACTIONS_PATH, farm.getData());
		ASObjectUtils.deleteByPath(FRIENDS_PATH, farm.getData());
		ASObjectUtils.deleteByPath(RATING_PATH, farm.getData());

		farm.save();
		conn.close();
		return "OK";
	}

	@SuppressWarnings("unchecked")
	private void processOutgoingActions(ASObject changes) {
		ASObject actionsForSend = new ASObject();
		ASObject farm_data;
		ASObject actions;
		ASObject outgoing;

		try {
			farm_data = (ASObject) changes.get("farm_data");
			actions = (ASObject) farm_data.get("actions");
			outgoing = (ASObject) actions.get("outgoing");
		} catch (NullPointerException e) {
			return; // actions not found
		}

		try {
			// collect all actions
			for (Object actionPackObj : outgoing.values()) {
				ASObject actionPack = (ASObject) actionPackObj;
				int receiverId = TypeUtils.getInteger(actionPack.get("uid"));
				ASObject actionContent = (ASObject) actionPack.get("action");
				if (!actionsForSend.containsKey(receiverId)) {
					actionsForSend
							.put(receiverId, new FarmActionsModel(Database
									.getInstance().getConnection(), receiverId));
				}
				FarmActionsModel receiverIncoming = (FarmActionsModel) actionsForSend
						.get(receiverId);
				receiverIncoming.addAction(actionContent);
			}

			// save actions in database
			for (Object farmAction : actionsForSend.values()) {
				FarmActionsModel farmActionMdl = (FarmActionsModel) farmAction;
				farmActionMdl.save();
				farmActionMdl.destroy();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
